#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import sys
import time
# 添加项目根目录到Python搜索路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import argparse
import logging
from typing import Dict, Any

from parser.java_ast_to_kg import JavaASTToKG
from graph.graph_connection import NebulaGraphConnection
from config.config import config  # 导入全局配置

def parse_args():
    """解析命令行参数"""
    parser = argparse.ArgumentParser(description='解析代码仓库并生成知识图谱')
    parser.add_argument('--repo-path', type=str, required=True, help='代码仓库路径')
    parser.add_argument('--language', type=str, default='java', help='编程语言（目前支持java）')
    parser.add_argument('--log-level', type=str, choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], 
                      default='INFO', help='日志级别，使用DEBUG可以查看详细SQL')
    # 允许通过命令行覆盖配置文件中的设置
    parser.add_argument('--nebula-ip', type=str, help='NebulaGraph IP地址（覆盖配置）')
    parser.add_argument('--nebula-port', type=int, help='NebulaGraph端口（覆盖配置）')
    parser.add_argument('--nebula-user', type=str, help='NebulaGraph用户名（覆盖配置）')
    parser.add_argument('--nebula-password', type=str, help='NebulaGraph密码（覆盖配置）')
    parser.add_argument('--nebula-space', type=str, help='NebulaGraph工作空间（覆盖配置）')
    return parser.parse_args()

def setup_logging(log_level):
    """配置日志"""
    numeric_level = getattr(logging, log_level, logging.INFO)
    
    # 创建logs目录（如果不存在）
    log_dir = "logs"
    os.makedirs(log_dir, exist_ok=True)
    
    # 生成日志文件名（使用当前时间）
    log_filename = os.path.join(log_dir, f"projectx_{time.strftime('%Y%m%d_%H%M%S')}.log")
    
    # 配置根logger，这会影响所有模块
    logging.basicConfig(
        level=numeric_level, 
        format='%(asctime)s - %(levelname)s - %(name)s - %(message)s',
        handlers=[
            # 同时输出到控制台和文件
            logging.StreamHandler(),  # 控制台处理器
            logging.FileHandler(log_filename, encoding='utf-8')  # 文件处理器
        ],
        force=True  # 强制重新配置，覆盖之前的设置
    )
    
    # 确保我们的模块都使用相同的日志级别
    logging.getLogger('parser').setLevel(numeric_level)
    logging.getLogger('graph').setLevel(numeric_level)
    
    logger = logging.getLogger(__name__)
    logger.debug("日志级别设置为: %s", log_level)
    logger.info(f"日志文件路径: {os.path.abspath(log_filename)}")
    return logger

def get_ast_converter(language: str, args):
    """
    根据语言获取对应的AST转换器
    
    Args:
        language: 编程语言
        args: 命令行参数
        
    Returns:
        对应语言的AST转换器
    """
    if language.lower() == 'java':
        return JavaASTToKG(enable_vector_storage=True)
    else:
        raise ValueError(f"不支持的语言: {language}")

def connect_to_nebula(args) -> NebulaGraphConnection:
    """
    连接到NebulaGraph数据库
    
    Args:
        args: 命令行参数
        
    Returns:
        NebulaGraph连接对象
    """
    # 从配置获取NebulaGraph连接信息
    nebula_config = config.get_nebula_config().copy()
    
    # 命令行参数覆盖配置文件
    if args.nebula_ip:
        nebula_config["ip"] = args.nebula_ip
    if args.nebula_port:
        nebula_config["port"] = args.nebula_port
    if args.nebula_user:
        nebula_config["user"] = args.nebula_user
    if args.nebula_password:
        nebula_config["password"] = args.nebula_password
    if args.nebula_space:
        nebula_config["space"] = args.nebula_space
    
    nebula_conn = NebulaGraphConnection(nebula_config)
    if not nebula_conn.connect():
        raise ConnectionError("无法连接到NebulaGraph数据库")
    return nebula_conn

def main():
    """主函数"""
    args = parse_args()
    
    # 设置日志级别
    logger = setup_logging(args.log_level)
    
    # 测试各种日志级别
    logger.debug("这是DEBUG级别日志 - 如果能看到此消息，说明DEBUG日志已开启")
    logger.info("这是INFO级别日志")
    logger.warning("这是WARNING级别日志")
    
    # 检查仓库路径是否存在
    if not os.path.exists(args.repo_path):
        logger.error(f"仓库路径不存在: {args.repo_path}")
        return 1
    
    try:
        # 获取AST转换器
        converter = get_ast_converter(
            language=args.language,
            args=args
        )
        
        # 连接到NebulaGraph
        graph_conn = connect_to_nebula(args)
        
        # 处理代码仓库
        file_extension = '.java' if args.language.lower() == 'java' else ''
        success_count, fail_count = converter.process_directory(args.repo_path, graph_conn, file_extension)
        
        logger.info(f"处理完成! 成功处理 {success_count} 个文件，失败 {fail_count} 个文件")
        
        # 关闭连接
        graph_conn.close()
        
        return 0
    except Exception as e:
        logger.error(f"处理过程中发生错误: {str(e)}")
        return 1

if __name__ == "__main__":
    sys.exit(main())    